package ai.people.core.standard.gather.service;

import ai.people.core.common.util.ApplicationContextUtil;
import ai.people.netmon.framework.domain.facebook.request.SyncDataRequest;
import ai.people.netmon.framework.domain.gather.config.GatherSyncExtended;
import ai.people.netmon.framework.domain.gather.request.GatherAccountData;
import ai.people.netmon.framework.domain.gather.response.GatherResponseBody;
import ai.people.netmon.framework.exception.enums.CommonEnum;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestTemplate;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

/**
 * 同步收集账号
 *
 * @author yuanqinglong
 * @date 2022/3/2 15:07
 */
public interface AccountGatherSyncService<T> {

    Logger LOGGER = LoggerFactory.getLogger(AccountGatherSyncService.class);

    /**
     * 同步收集账号
     *
     * @param account            账户
     * @param dataSyncUrl        数据同步url
     * @param gatherSyncExtended 收集同步扩展
     */
    default void syncGatherAccount(List<T> account, String dataSyncUrl, GatherSyncExtended gatherSyncExtended) {
        ExecutorService executorService = ApplicationContextUtil.getBean(ExecutorService.class, "defaultThreadPoolExecutor");
        RestTemplate restTemplate = ApplicationContextUtil.getBean(RestTemplate.class);
        executorService.execute(() -> {
            List<List<T>> partition = Lists.partition(account, gatherSyncExtended.getLimit());
            for (List<T> partitionAccount : partition) {
                List<GatherAccountData> accountDataList = partitionAccount.stream().map(accountGather -> JSONObject.parseObject(JSONObject.toJSONString(accountGather), GatherAccountData.class)).collect(Collectors.toList());
                SyncDataRequest<GatherAccountData> body = new SyncDataRequest<>(accountDataList);
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                HttpEntity<SyncDataRequest<GatherAccountData>> request = new HttpEntity<>(body, headers);
                for (int integer = 0; integer < gatherSyncExtended.getNumberOfRetries(); integer++) {
                    LOGGER.info("请求url:{} 等待返回...", dataSyncUrl);
                    GatherResponseBody result;
                    try {
                        result = restTemplate.postForObject(dataSyncUrl, request, GatherResponseBody.class);
                    }catch (Exception e){
                        LOGGER.error(e.getMessage(),e);
                        continue;
                    }
                    LOGGER.info("请求url:{} 返回:{}", dataSyncUrl, JSONObject.toJSONString(result));
                    Integer status = Optional.ofNullable(result).map(GatherResponseBody::getStatus).orElse(null);
                    if (Objects.equals(status, CommonEnum.SUCCESS.getCode())) {
                        this.updateCollectionStatus(partitionAccount);
                        break;
                    }
                }
            }
        });
    }


    /**
     * 更新采集状态
     *
     * @param account 账户
     */
    void updateCollectionStatus(List<T> account);

}
